package com.kelvem.saas.workbanch.core.system.service;

import com.kelvem.saas.workbanch.core.base.BaseCriteria;
import com.kelvem.saas.workbanch.core.base.BaseService;
import com.kelvem.saas.workbanch.core.base.Page;
import com.kelvem.saas.workbanch.core.exception.SaasAssert;
import com.kelvem.saas.workbanch.core.exception.SaasException;
import com.kelvem.saas.workbanch.core.manager.dto.OrgUrlDto;
import com.kelvem.saas.workbanch.security.shiro.encoder.BCryptPasswordEncoder;
import com.kelvem.saas.workbanch.core.system.dao.SysUserDao;
import com.kelvem.saas.workbanch.core.system.model.SysUserEntity;
import com.kelvem.saas.workbanch.core.system.request.SysUserQueryVo;
import com.kelvem.saas.workbanch.core.utils.DateUtil;
import com.kelvem.saas.workbanch.fsm.dao.BaseDao;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 用户表Service
 *
 * @author kelvem
 * @version 1.0
 */
@Service
@Slf4j
public class SysUserService extends BaseService<SysUserEntity, SysUserQueryVo> {

    @Resource
    private BCryptPasswordEncoder bcryptPasswordEncoder;

    @Resource
    private SysUserDao sysUserDao;

    /**
     * 增加用户表
     *
     * @param sysUser 用户表信息
     * @return Long 主键
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addSysUser(SysUserEntity sysUser) {
        
        log.info("SysUserService:addSysUser:start, sysUser=【{}】", sysUser);
        SaasAssert.notNull(sysUser);
        SaasAssert.notNull(sysUser.getUsername());
        SaasAssert.notNull(sysUser.getPassword());
        SaasAssert.notNull(sysUser.getStatus());

        try {
            // hash
            String pwd = bcryptPasswordEncoder.hash(sysUser.getPassword());
            sysUser.setPassword(pwd);

            if (sysUser.getAvatar() == null) {
                sysUser.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            }
            if (sysUser.getCreateTime() == null) {
                sysUser.setCreateTime(DateUtil.now());
            }
            if (sysUser.getUpdateTime() == null) {
                sysUser.setUpdateTime(DateUtil.now());
            }
        
            sysUserDao.insert(sysUser);
            Long sysUserId = sysUser.getId();
            log.info("SysUserService:addSysUser:end, sysUserId={}", sysUserId);
        
            return sysUser.getId();
        } catch (Exception e) {
            String msg = String.format("SysUserService:addSysUser:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 修改用户表
     *
     * @param sysUser 用户表信息
     * @return 更新记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateSysUser(SysUserEntity sysUser) {
        
        log.info("SysUserService:updateSysUser:start, sysUser=【{}】", sysUser);
        SaasAssert.notNull(sysUser);
        SaasAssert.notNull(sysUser.getId());

        try {
            int count = sysUserDao.updateById(sysUser);
            log.info("SysUserService:updateSysUser:end, count={}", count);
            return count;
        } catch (Exception e) {
            String msg = String.format("SysUserService:updateSysUser:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 删除用户表
     *
     * @param sysUserId 用户表id
     * @return 删除记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteSysUser(Long sysUserId) {

        log.info("SysUserService:deleteSysUser:start, sysUserId={}", sysUserId);
        SaasAssert.notNull(sysUserId);
        
        try {
            int count = sysUserDao.deleteById(sysUserId);
            log.info("SysUserService:deleteSysUser:end, count={}", count);
            return count;
        } catch (Exception e) {
            String msg = String.format("SysUserService:deleteSysUser:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }
    
    /**
     * 查询用户表分页数据
     *
     * @param sysUserQueryVo 查询用
     * @return Page<SysUserDto>
     */
    public Page<SysUserEntity> querySysUserPage(SysUserQueryVo sysUserQueryVo) {
        
        log.info("SysUserService:querySysUserPage:start, sysUserQueryVo=【{}】", sysUserQueryVo);
        SaasAssert.notNull(sysUserQueryVo);
        
        try {
            Page<SysUserEntity> page = super.queryPage(sysUserQueryVo);
            log.info("SysUserService:querySysUserPage:end, page.size={}", page.getRecords().size());
            return page;
        } catch (Exception e) {
            String msg = String.format("SysUserService:querySysUserPage:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 查询用户表列表数据
     *
     * @param sysUserQueryVo 查询用
     * @return List<SysUser>
     */
    public List<SysUserEntity> querySysUserList(SysUserQueryVo sysUserQueryVo) {
        
        log.info("SysUserService:querySysUserList:start, sysUserQueryVo=【{}】", sysUserQueryVo);
        SaasAssert.notNull(sysUserQueryVo);
        
        try {
            List<SysUserEntity> list = super.queryList(sysUserQueryVo);
            log.info("SysUserService:querySysUserList:end, list.size={}", list.size());
            return list;
        } catch (Exception e) {
            String msg = String.format("SysUserService:querySysUserList:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 根据id查询用户表信息
     *
     * @param sysUserId 用户表id
     * @return SysUser
     */
    public SysUserEntity getSysUserById(Long sysUserId) {

        log.info("SysUserService:getSysUserById:start, sysUserId={}", sysUserId);
        SaasAssert.notNull(sysUserId);
        
        try {
            SysUserEntity sysUser = sysUserDao.selectById(sysUserId);
            log.info("SysUserService:getSysUserById:end, sysUserInfo=【{}】", sysUser);
            return sysUser;
        } catch (Exception e) {
            String msg = String.format("SysUserService:getSysUserById:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
    }

    /**
     * 构建查询用Criteria
     * 基类的queryPage, queryList方法使用
     *
     * @param queryVo 查询用
     * @return BaseCriteria
     */
    @Override
    public BaseCriteria<SysUserEntity> buildQueryCriteria(SysUserQueryVo queryVo) {
        BaseCriteria<SysUserEntity> criteria = new BaseCriteria<>();
        criteria.orderByDesc("id");
        
        // 主键
        Long id = queryVo.getId();
        if (super.isNotEmpty(id)) {
            criteria.andEqualTo("id", queryVo.getId());
        }
        
        // 创建时间
        Date startCreateTime = queryVo.getStartCreateTime();
        if(super.isNotEmpty(startCreateTime)) {
            criteria.andGreaterThanOrEqualTo("createTime", startCreateTime);
        }
        Date endCreateTime = queryVo.getEndCreateTime();
        if(super.isNotEmpty(endCreateTime)) {
            criteria.andLessThanOrEqualTo("createTime", endCreateTime);
        }

        // 最后登陆时间
        Date startLastLoginTime = queryVo.getStartLastLoginTime();
        if (super.isNotEmpty(startLastLoginTime)) {
            criteria.andGreaterThanOrEqualTo("lastLoginTime", startLastLoginTime);
        }
        Date endLastLoginTime = queryVo.getEndLastLoginTime();
        if (super.isNotEmpty(endLastLoginTime)) {
            criteria.andLessThanOrEqualTo("lastLoginTime", endLastLoginTime);
        }

        // 生日
        Date birthday = queryVo.getBirthday();
        if (super.isNotEmpty(birthday)) {
            criteria.andEqualTo("birthday", birthday);
        }

        // 性别, 1:男; 0:女
        Integer sex = queryVo.getSex();
        if (super.isNotEmpty(sex)) {
            criteria.andEqualTo("sex", sex);
        }

        // 是否是超级管理员, 1:是; 0:否
        Integer adminFlag = queryVo.getAdminFlag();
        if (super.isNotEmpty(adminFlag)) {
            criteria.andEqualTo("adminFlag", adminFlag);
        }

        // 来源类型,system:系统; manual:人工; copy:拷贝
        String sourceType = queryVo.getSourceType();
        if (super.isNotEmpty(sourceType)) {
            criteria.andEqualTo("sourceType", sourceType);
        }

        // 是否删除, 1:被删除; 0:未删除
        Integer delFlag = queryVo.getDelFlag();
        if (super.isNotEmpty(delFlag)) {
            criteria.andEqualTo("delFlag", delFlag);
        }

        // 创建人
        String createUid = queryVo.getCreateUid();
        if (super.isNotEmpty(createUid)) {
            criteria.andEqualTo("createUid", createUid);
        }

        // 更新人
        String updateUid = queryVo.getUpdateUid();
        if (super.isNotEmpty(updateUid)) {
            criteria.andEqualTo("updateUid", updateUid);
        }

        // 租户id
        Long tenantId = queryVo.getTenantId();
        if (super.isNotEmpty(tenantId)) {
            criteria.andEqualTo("tenantId", tenantId);
        }

        // 用户名
        String username = queryVo.getUsername();
        if (super.isNotEmpty(username)) {
            criteria.andEqualTo("username", username);
        }

        return criteria;
    }

    @Override
    public BaseDao<SysUserEntity> getDao() {
        return this.sysUserDao;
    }


    /**
     * 根据username查询用户信息
     *
     * @param username 账户名
     * @return SysUser 用户信息
     */
    public SysUserEntity getSysUserByUsername(String username) {
        log.info("SysUserService:getSysUserByUsername:start, username=【{}】", username);
        SaasAssert.notNull(username);

        try {
            SysUserQueryVo sysUserQueryVo = SysUserQueryVo.builder().username(username).build();
            List<SysUserEntity> list = super.queryList(sysUserQueryVo);
            if (list.size() == 1) {
                SysUserEntity result = list.get(0);
                log.info("SysUserService:getSysUserByUsername:end, SysUser={}", result);
                return result;
            } else if (list.size() > 1) {
                log.warn("getSysUserByUsername result too many, username={}, list.size={}", username, list.size());
            }
        } catch (Exception e) {
            String msg = String.format("SysUserService:getSysUserByUsername:error, %s", e.getMessage());
            log.error(msg, e);
            throw new SaasException(msg);
        }
        // 未查询到或查询过多, 返回null
        return null;
    }

    public List<OrgUrlDto> queryAllOrgUrlList() {
        return this.sysUserDao.queryAllOrgUrlList();
    }
}
